package main

//typedef const char uplink_const_char;
import "C"
import (
	"common/kms"
	"common/log"
	"context"
	"euplink"
	"euplink/config"
	"fmt"
	"go.uber.org/zap"
	"os"
	"sort"
	"strings"
	"sync"
	"time"
)

var proj *euplink.Project = nil
var gConfig config.Config
var glog *zap.Logger = nil
var once sync.Once

func initOnece(apiKey, centerEndpoint *C.uplink_const_char) int {

	var err error
	fmt.Println("apkeyString", C.GoString(apiKey))
	ctx := context.Background()
	gConfig = config.Config{
		//CenterUrl:  "estore.guanjieai.com:10000",
		CenterUrl:  C.GoString(centerEndpoint),
		MaxSegment: 20000000,
		UseP2P:     true,
		UseKms:     false,
		Kms: kms.Config{
			BaseUrl:            "https://47.106.76.249:9000",
			AppId:              "f12ce38f-069b-4cbd-9ba1-ee4846200fea",
			AppKey:             "wevKrmDsxu9v9CEFevNbRDxjYP2AP3ig",
			Timeout:            time.Second * 30,
			InsecureSkipVerify: true,
		},
		DefaultBucket: "default",
		ApiKey:        C.GoString(apiKey),
		DebugDevice:   "",
	}
	logCfg := log.Config{
		File:        "",
		FileSize:    10,
		FileBackups: 10,
		FileAge:     30,
		Level:       "debug",
		Output:      "any",
		Encoder:     "console",
	}
	zapLog := log.NewZapLog(&logCfg)
	glog = zapLog

	proj, err = euplink.NewProject(ctx, gConfig, zapLog)
	if err != nil {
		fmt.Println("error NewProject", err)
		return -1
	}
	fmt.Println("init ok")
	return 0
}

//export Init
func Init(apiKey, centerEndpoint *C.uplink_const_char) int {
	var ret = 0
	once.Do(func() {
		ret = initOnece(apiKey, centerEndpoint)
	})
	return ret
}

//export DownloadFile
func DownloadFile(key, outFile *C.uplink_const_char) int {
	fmt.Println("key", C.GoString(key))
	fmt.Println("out", C.GoString(outFile))

	outFp, err := os.OpenFile(C.GoString(outFile), os.O_WRONLY|os.O_CREATE, os.ModePerm)
	if err != nil {
		fmt.Println("download:create file: ", C.GoString(outFile), " err: ", err)
	}
	defer outFp.Close()
	ctx := context.Background()
	err = proj.DownloadObject(ctx, gConfig.DefaultBucket, C.GoString(key), outFp)
	if err != nil {
		glog.Error("DownloadObject", zap.Error(err))
		return -1
	}
	return 0
}

//export UploadFile
func UploadFile(key, infile *C.uplink_const_char) int {
	ctx := context.Background()
	fileName := C.GoString(infile)
	fs, err := os.Stat(fileName)
	if err != nil {
		glog.Error("UploadFile", zap.Error(err))
		return -1
	}
	fp, err := os.Open(fileName)
	if err != nil {
		glog.Error("Open file ", zap.String("file", fileName), zap.Error(err))
		return -1
	}
	err = proj.UploadObject(ctx, gConfig.DefaultBucket, C.GoString(key), fp, false, fs.Size(), nil)
	if err != nil {
		glog.Error("UploadFile", zap.Error(err))
		return -1
	}
	return 0
}

//export DeleteObject
func DeleteObject(key *C.uplink_const_char) int {
	ctx := context.Background()
	err := proj.DeleteObject(ctx, gConfig.DefaultBucket, C.GoString(key))
	if err != nil {
		glog.Error("UploadFile", zap.Error(err))
		return -1
	}
	return 0
}

//export GetUploadProgress
func GetUploadProgress() int {
	return proj.GetUploadProgress()
}

//export GetDownloadProgress
func GetDownloadProgress() int {
	return proj.GetDownloadProgress()
}

//export StopDownload
func StopDownload() int {
	return 0
}

//export TestInt
func TestInt(a int) int {
	return 0
}

//export ListFiles
func ListFiles(keyPrefix *C.uplink_const_char) *C.char {
	ctx := context.Background()
	var resultString string

	items, err := proj.ListObject(ctx, gConfig.DefaultBucket, C.GoString(keyPrefix), "")
	if err != nil {
		return C.CString(resultString)
	}
	var results []string
	for _, item := range items {
		results = append(results, item.ObjectKey)
	}
	sort.Strings(results)
	resultString = strings.Join(results, ",")
	return C.CString(resultString)
}

func main() {}
